#ifndef prs_FrmGeomSize_H
#define prs_FrmGeomSize_H

#include "prs_FrmNodes.h"
#include "prs_FrmValue.h"
#include "frm_geometry.h"

namespace prs {

///////////////////////////////////////////////////////////////////////////////

struct TNodeFrmGeomSize : public TNodeFrm
{
  //DECLARE_AbstractClientNode();
  //
  enum EType
  {
    EType_Fixed,
    EType_Parent,
    EType_ChildrenSum,
    EType_ChildrenMax,
    EType_ChildrenMaxBase,
    EType_SiblingsRem,
    EType_SiblingsMax
  };
  //
  TAttrInteger<attrName_Size> Size;
  //
  TNodeFrmGeomSize() : Size(this) { Size = 0;}
  //
  virtual EType GetEType()=0;
  virtual frm::geometry::TCalcSize *NewOld()=0;
};

///////////////////////////////////////////////////////////////////////////////

struct TFrmGeomSizeValue : public TFrmPointerNodeOwnerValue<TNodeFrmGeomSize*>
{
  DECLARE_ClientNodeEx(nodeType_TFrmGeomSizeValue)
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

struct TNodeFrmGeomSizeFixed : public TNodeFrmGeomSize
{
  DECLARE_ClientNode();
  //
  TNodeFrmGeomSizeFixed()         {}
  TNodeFrmGeomSizeFixed(int Size) { this->Size = Size;}
  //
  virtual EType GetEType()                   { return EType_Fixed;}
  virtual frm::geometry::TCalcSize *NewOld() { return new frm::geometry::TFixed(Size.GetValue());}
};

///////////////////////////////////////////////////////////////////////////////

struct TNodeFrmGeomSizeParent : public TNodeFrmGeomSize
{
  DECLARE_ClientNode();
  //
  virtual EType GetEType()                   { return EType_Parent;}
  virtual frm::geometry::TCalcSize *NewOld() { return new frm::geometry::TParent;}
};

///////////////////////////////////////////////////////////////////////////////

struct TNodeFrmGeomSizeChildrenSum : public TNodeFrmGeomSize
{
  DECLARE_ClientNode();
  //
  virtual EType GetEType()                   { return EType_ChildrenSum;}
  virtual frm::geometry::TCalcSize *NewOld() { return new frm::geometry::TChildrenSum;}
};

///////////////////////////////////////////////////////////////////////////////

struct TNodeFrmGeomSizeChildrenMax : public TNodeFrmGeomSize
{
  DECLARE_ClientNode();
  //
  virtual EType GetEType()                   { return EType_ChildrenMax;}
  virtual frm::geometry::TCalcSize *NewOld() { return new frm::geometry::TChildrenMax;}
};

///////////////////////////////////////////////////////////////////////////////

struct TNodeFrmGeomSizeChildrenMaxBase : public TNodeFrmGeomSize
{
  DECLARE_ClientNode();
  //
  virtual EType GetEType()                   { return EType_ChildrenMaxBase;}
  virtual frm::geometry::TCalcSize *NewOld() { return new frm::geometry::TChildrenMaxBase;}
};

///////////////////////////////////////////////////////////////////////////////

struct TNodeFrmGeomSizeSiblingsRem : public TNodeFrmGeomSize
{
  DECLARE_ClientNode();
  //
  virtual EType GetEType()                   { return EType_SiblingsRem;}
  virtual frm::geometry::TCalcSize *NewOld() { return new frm::geometry::TSiblingsRem;}
};

///////////////////////////////////////////////////////////////////////////////

struct TNodeFrmGeomSizeSiblingsMax : public TNodeFrmGeomSize
{
  DECLARE_ClientNode();
  //
  virtual EType GetEType()                   { return EType_SiblingsMax;}
  virtual frm::geometry::TCalcSize *NewOld() { return new frm::geometry::TSiblingsMax;}
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

struct TRuleFrmGeomSize //: public snt::TRule
{
  snt::TRule RWidth,RHeight,RValue;
  //
  TRuleFrmGeomSize(
    snt::text::TContext &SntContext
  );
  //
  void EnableSetParamAsIdent(bool V) { vEnSetParamAsIdent = V;}
  void SetAttr(TAttrPointerBase *Attr)  { attr = Attr;}

private:  
  void FEnableSetParamAsIdent(snt::TParams &Params);
  bool FSetNumber(snt::text::TNumber::TFuncClosureDoEntryParams &Params);
  void FGetEnumSize(snt::text::TEnumSet::TFuncGetEnumSetParams &Params);
  bool FSetEnumSize(snt::text::TEnumSet::TFuncDoEntryParams    &Params);
  bool FSetParamAsIdent(snt::text::TIdent::TFuncClosureDoEntryParams &Params);
  //
  struct TType : public svl::TEnumSet {
    TType() : svl::TEnumSet (
      "parent",TNodeFrmGeomSize::EType_Parent,
      "childrenSum",TNodeFrmGeomSize::EType_ChildrenSum,
      "childrenMax",TNodeFrmGeomSize::EType_ChildrenMax,
      "childrenMaxBase",TNodeFrmGeomSize::EType_ChildrenMaxBase,
      "siblingsRem",TNodeFrmGeomSize::EType_SiblingsRem,
      "siblingsMax",TNodeFrmGeomSize::EType_SiblingsMax
    ){}
  };
  //
  static TType Type;
  
  static TNodeFrmGeomSizeFixed Fixed; 
  static TNodeFrmGeomSizeParent Parent; 
  static TNodeFrmGeomSizeChildrenSum ChildrenSum; 
  static TNodeFrmGeomSizeChildrenMax ChildrenMax; 
  static TNodeFrmGeomSizeChildrenMaxBase ChildrenMaxBase; 
  static TNodeFrmGeomSizeSiblingsRem SiblingsRem; 
  static TNodeFrmGeomSizeSiblingsMax SiblingsMax; 

  svl::TVariant vEnSetParamAsIdent;
  TAttrPointerBase *attr;
  svl_Except;
};

///////////////////////////////////////////////////////////////////////////////
}

#endif
